package net.hpxn.gsmc.core.event;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.hpxn.gsmc.config.ConfigFactory;
import net.hpxn.gsmc.config.map.Map;
import net.hpxn.gsmc.config.map.Map.Mapping;
import net.hpxn.gsmc.core.server.Server;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

public abstract class BaseEvent {

	protected String rawEvent;

	public abstract HashMap<String, String> getPlayerMap();

	public abstract HashMap<String, String> getParameterMap();

	public abstract String stripPlayerInfo( String pRawEvent );

	protected Server server;
	protected HashMap<String, String> playerMap;
	protected HashMap<String, String> parameterMap;
	protected Logger log;
	protected static Map rawMap;

	public BaseEvent( String pEvent, Server pServer ) {
		super();

		this.rawEvent = StringUtils.chomp( pEvent.trim() );
		this.server = pServer;
		log = Logger.getLogger( getClass().getCanonicalName() );

		if ( rawMap == null ) {
			try {
				rawMap = ConfigFactory.getMapConfig( pServer.getGameType() );
			} catch ( Exception e ) {
				log.error( "Unable to load mapping file for game type: "
						+ server.getGameType() );
			}
		}
	}

	/**
	 * Returns the server that the event occurred upon.
	 * 
	 * @return Server
	 */
	public Server getServer() {
		return server;
	}

	/**
	 * Returns the raw event as received from the server with some cleaning.
	 * 
	 * @return String
	 */
	public String getRawEvent() {
		return rawEvent;
	}

	/**
	 * Returns a list of Mappings that are triggered by this event. The mappings
	 * contain actions which are fully qualified class names.
	 * 
	 * @return ArrayList<Mapping> empty list if no matches
	 * @throws Exception
	 */
	public ArrayList<Mapping> getMappingList() {
		ArrayList<Mapping> wMappings = new ArrayList<Mapping>();
		for ( Mapping wMapping : rawMap.getMapping() ) {
			Matcher wMatcher = Pattern.compile( wMapping.getTrigger() )
					.matcher( stripPlayerInfo( rawEvent ) );

			if ( wMatcher.lookingAt() ) {
				wMappings.add( wMapping );
			}
		}
		return wMappings;
	}

	public String stripDateTime( String pEvent ) {
		return pEvent
				.substring( pEvent.indexOf( ":", 26 ) + 2, pEvent.length() );
	}

}